package gui;


import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import org.jdesktop.swingx.decorator.Filter;
import org.jdesktop.swingx.decorator.FilterPipeline;
import org.jdesktop.swingx.decorator.PatternFilter;

import tools.ZipTools;


import database.DatabaseManager;
import database.Package;
import database.Release;
import database.ReleaseIdentifier;


/**
 * @author aioros
 * 
 * Container which group all actions feature (singleton)
 */
public class ActionContainer extends Container {

	
	/*-------------------- Fields ------------------------*/
	
	private static final long serialVersionUID = 168897L;
	
	
	/**
	 * update path icone
	 */
	public static final String UPDATE_PATH_ICON = "ressources/images/update.png";
	
	
	/**
	 * update path icone
	 */
	public static final String INSTALL_PATH_ICON = "ressources/images/install.png";
	
	
	/**
	 * the single object ActionContainer
	 */
	private static ActionContainer actionContainer = new ActionContainer();
	
	/**
	 * intput text in search bar
	 */
	private JTextField intputText; 
	
	
	
	/*-------------------- Constructor ------------------------*/
	
	/**
	 * the constructor is private in order to create a singleton
	 */
	private ActionContainer(){
		super();
		
		this.setLayout(new GridLayout(2,2));
		
		Container searcherContainer = this.createSearcher();
		Container radioBtnCategoryContainer = this.createJRadioButtonsCategory();
		Container btnContainer = this.createButtons();
		Container radioBtnsInstallContainer = this.createJRadioButtonsInstall();
		
		this.add(searcherContainer);
		this.add(radioBtnCategoryContainer);
		this.add(btnContainer);
		this.add(radioBtnsInstallContainer);
	}
	
	
	
	
	/*-------------------- Methodes ------------------------*/
	
	
	/**
	 * create Radio Buttons category
	 */
	private Container createJRadioButtonsCategory(){
		
		/* Create the radio buttons.*/
	    JRadioButton stableButton = new JRadioButton("stable");
	    stableButton.setMnemonic(KeyEvent.VK_S);
	    stableButton.setActionCommand("stable");

	    JRadioButton developmentButton = new JRadioButton("development");
	    developmentButton.setMnemonic(KeyEvent.VK_D);
	    developmentButton.setActionCommand("development");

	    JRadioButton bothButton = new JRadioButton("both");
	    bothButton.setMnemonic(KeyEvent.VK_B);
	    bothButton.setActionCommand("both");
	    bothButton.setSelected(true);

	    /*Group the radio buttons.*/
	    ButtonGroup group = new ButtonGroup();
	    group.add(stableButton);
	    group.add(developmentButton);
	    group.add(bothButton);

	    /* action definition */
	    stableButton.addActionListener( new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				
				PackagesJXTable.getPackagesJXTable().setCategoryFilter("stable");
			}
	    });
	    
	    developmentButton.addActionListener( new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				
				PackagesJXTable.getPackagesJXTable().setCategoryFilter("development");
			}
	    });
	    
	    bothButton.addActionListener( new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				
				PackagesJXTable.getPackagesJXTable().setCategoryFilter(".*");
			}
	    });
	    
	    JLabel category = new JLabel("category : ");
	    
	    /* container configuration */
	    Container radioBtnContainer = new Container();
	    
	    radioBtnContainer.add(category);
	    radioBtnContainer.add(stableButton);
	    radioBtnContainer.add(developmentButton);
	    radioBtnContainer.add(bothButton);
	    
	    radioBtnContainer.setLayout(new FlowLayout());
	    
	    return radioBtnContainer;
	}
	
	
	/**
	 * create Radio Buttons state 
	 */
	private Container createJRadioButtonsInstall(){
		
		/* Create the radio buttons.*/
	    JRadioButton notInstalledButton = new JRadioButton("not installed");
	    notInstalledButton.setMnemonic(KeyEvent.VK_N);
	    notInstalledButton.setActionCommand("not installed");
	    notInstalledButton.setSelected(true);

	    JRadioButton installedButton = new JRadioButton("installed");
	    installedButton.setMnemonic(KeyEvent.VK_N);
	    installedButton.setActionCommand("installed");

	    /*Group the radio buttons.*/
	    ButtonGroup group = new ButtonGroup();
	    group.add(notInstalledButton);
	    group.add(installedButton);
	    
	    int col = PackagesJXTable.getPackagesJXTable().getColumn("Install").getModelIndex();
		PackagesJXTable.getPackagesJXTable().setFilters(new FilterPipeline(
	        new Filter[] { new PatternFilter("not", 0, col) }));

	    /* action definition */
	    notInstalledButton.addActionListener( new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				
				PackagesJXTable.getPackagesJXTable().setInstallFilter("not");
			}
	    });
	    
	    installedButton.addActionListener( new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				
				PackagesJXTable.getPackagesJXTable().setInstallFilter("^(i)");
			}
	    });
	    
	    JLabel install = new JLabel("install : ");
	    
	    /* container configuration */
	    Container radioBtnContainer = new Container();
	    
	    radioBtnContainer.add(install);
	    radioBtnContainer.add(notInstalledButton);
	    radioBtnContainer.add(installedButton);
	    
	    radioBtnContainer.setLayout(new FlowLayout());
	    
	    return radioBtnContainer;
	}
	
	
	
	/**
	 * create install and update buttons
	 */
	private Container createButtons(){
		
		/* create buttons */
		JButton UpdateButton = new JButton("Update");
		JButton InstallButton = new JButton("Install");
		
		ImageIcon UpdateButtonIcon = new ImageIcon(ActionContainer.UPDATE_PATH_ICON);
	    ImageIcon InstallButtonIcon = new ImageIcon(ActionContainer.INSTALL_PATH_ICON);
		
		UpdateButton.setIcon(UpdateButtonIcon);
		InstallButton.setIcon(InstallButtonIcon);
		
		/* action definition */
		UpdateButton.addActionListener( new ActionListener(){

			public void actionPerformed(ActionEvent e) {

				DatabaseManager.getDatabaseManager().upDateDatabase(
						DatabaseManager.DEFAULT_URL_UPDATE +
						DatabaseManager.getDatabaseManager().getLocalDatabase().getVersion());
				PackagesJXTable.getPackagesJXTable().initialize();
			}
	    });
	    
		InstallButton.addActionListener( new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				
				ActionContainer.this.install();
			}
	    });
	    
		/* container configuration */
		Container btnContainer = new Container();
		
		btnContainer.add(UpdateButton);
		btnContainer.add(InstallButton);
		
		btnContainer.setLayout(new FlowLayout());
		
		return btnContainer;
	}
	
	
	
	
	/**
	 * create search interface
	 */
	private Container createSearcher(){
		
		/* create search interface */
		JLabel search = new JLabel("search : ");
		this.intputText = new JTextField(); 
		intputText.setColumns(30);
		JButton searchButton = new JButton("Search");
		
		/* action definition */
		
		DocumentListener documentListener = new DocumentListener()  {

				public void changedUpdate(DocumentEvent arg0) {
					PackagesJXTable.getPackagesJXTable().setSearchFilter(ActionContainer.this.intputText.getText());
				}
	
				public void insertUpdate(DocumentEvent arg0) {
					PackagesJXTable.getPackagesJXTable().setSearchFilter(ActionContainer.this.intputText.getText());
				}
	
				public void removeUpdate(DocumentEvent arg0) {
					PackagesJXTable.getPackagesJXTable().setSearchFilter(ActionContainer.this.intputText.getText());
				}
			};

		this.intputText.getDocument().addDocumentListener(documentListener);

		
		intputText.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				PackagesJXTable.getPackagesJXTable().setSearchFilter(ActionContainer.this.intputText.getText());
			}
	    });
		
		searchButton.addActionListener( new ActionListener(){

			@SuppressWarnings("deprecation")
			public void actionPerformed(ActionEvent e) {

				PackagesJXTable.getPackagesJXTable().setSearchFilter(ActionContainer.this.intputText.getText());
			}
	    });
		
		/* container configuration */
		Container searcherContainer = new Container();
		
		searcherContainer.add(search);
		searcherContainer.add(intputText);
		searcherContainer.add(searchButton);
		
		searcherContainer.setLayout(new FlowLayout());
		
		return searcherContainer;
	}
	
	
	/**
	 * install the release selected
	 */
	private void install(){
		
		ReleaseIdentifier currentRls = PackagesJXTable.getPackagesJXTable().getCurrentRelease();
		
		if (currentRls != null){
			
			Package p = DatabaseManager.getDatabaseManager().getLocalDatabase().getPackages().get(currentRls.getPackageID());
			Release r = p.getBranches().get(currentRls.getBranchID()).getReleases().get(currentRls.getReleaseID());
			if (r.getInstall().equals("not installed")){
				
				String endUrl =  	currentRls.getPackageID() + "/" +
									currentRls.getBranchID() + "/" +
									currentRls.getReleaseID() + "/" ;
				
				String zipName = 	p.getName() +
									r.getVersion() +
									".cpkg";
				System.out.println(DatabaseManager.DEFAULT_PATH_INSTALL);
				// file download
				DatabaseManager.getDatabaseManager().fileDownload(DatabaseManager.DEFAULT_URL_INSTALL + 
						endUrl + zipName);
				
				// unzip the file
				try {
					File zipFile = new File(DatabaseManager.DEFAULT_PATH_INSTALL + zipName);
					ZipTools.unzip(zipFile, DatabaseManager.DEFAULT_PATH_INSTALL);
					zipFile.delete();
					
					
					// save the database and change the release status
					r.setInstall("installed");
					DatabaseManager.getDatabaseManager().saveLocalDatabase();
					PackagesJXTable.getPackagesJXTable().initialize();
				} catch (IOException e1) {
					JOptionPane.showMessageDialog(CeroRepositoryClient.getCeroRepositoryClient(),
							"IO Error",
							"Error",
							JOptionPane.ERROR_MESSAGE);
				}
			}
		}
	}
	
	
	
	/**
	 * @return the single object ActionContainer
	 */
	public static ActionContainer getActionContainer(){
		
		return actionContainer;
	}




	public JTextField getIntputText() {
		return intputText;
	}




	public void setIntputText(JTextField intputText) {
		this.intputText = intputText;
	}
	
}
